package org.opens.apache.http;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Map;

public class HttpUtil {

    private static Log LOGGER = LogFactory.get(HttpUtil.class);

    private static final RequestConfig requestConfig;

    private static final RequestConfig uploadConfig;

    static {
        requestConfig = RequestConfig.custom()
                // 客户端和服务器建立连接的timeout
                .setConnectTimeout(3000)
                // 指从连接池获取连接的timeout
                .setConnectionRequestTimeout(6000)
                // 客户端从服务器读取数据的timeout
                .setSocketTimeout(7000)
                .build();
        uploadConfig = RequestConfig.custom()
                // 客户端和服务器建立连接的timeout
                .setConnectTimeout(1000 * 60 * 20)
                // 指从连接池获取连接的timeout
                .setConnectionRequestTimeout(6000)
                // 客户端从服务器读取数据的timeout
                .setSocketTimeout(1000 * 60 * 20)
                .build();
    }

    private static final Integer CONNECT_TIMEOUT = 15000;
    private static final Integer REND_TIMEOUT = 60000;


    public static String get(String url, Map<String, Object> params) {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        CloseableHttpResponse response = null;
        String result = "";

        try {
            URIBuilder uriBuilder = new URIBuilder(url);
            for (String key : params.keySet()) {
                uriBuilder.addParameter(key, params.get(key).toString());
            }
            HttpGet httpGet = new HttpGet(uriBuilder.build());
            System.out.println(uriBuilder.build());
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(2000) //服务器响应超时时间
                    .setConnectTimeout(2000) //连接服务器超时时间
                    .build();
            httpGet.setConfig(requestConfig);
            httpGet.setHeader("Content-Type", "application/x-www-form-urlencoded");
            response = httpClient.execute(httpGet);
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                //System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                result = EntityUtils.toString(responseEntity, "UTF-8");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            System.err.println("解析错误");
            e.printStackTrace();
        } catch (URISyntaxException e) {
            System.err.println("URI解析异常");
            e.printStackTrace();
        } finally {
            // 释放连接
            IOUtils.closeQuietly(response);
            IOUtils.closeQuietly(httpClient);
        }
        return result;
    }

    public static void postWithJson(String url, Map<String, Object> param) {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        CloseableHttpResponse response = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(2000) //服务器响应超时时间
                    .setConnectTimeout(2000) //连接服务器超时时间
                    .build();
            httpPost.setConfig(requestConfig);

            JSONObject jsonObject = new JSONObject();
            StringEntity entity = new StringEntity(JSON.toJSONString(jsonObject), "utf-8");//也可以直接使用JSONObject
            httpPost.setEntity(entity);
            httpPost.setHeader("Content-Type", "application/json;charset=utf8");
            // 由客户端执行(发送)请求
            response = httpClient.execute(httpPost);
            System.out.println("响应状态为:" + response.getStatusLine());
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(response);
            IOUtils.closeQuietly(httpClient);
        }
    }

    public static String httpPostWithJson2(String url, String json) throws IOException {
        String result = "";
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            BasicResponseHandler handler = new BasicResponseHandler();
            StringEntity entity = new StringEntity(json, "utf-8");//解决中文乱码问题
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            result = httpClient.execute(httpPost, handler);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(httpClient);
        }
        return result;
    }

    /**
     * 发送post请求，form-data数据传输
     * POST multipart/form-data
     *
     * @param url 请求地址
     * @return 返回json数据
     */
    public static JSONObject doPostFormData(String url, Map<String, String> formData) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            LOGGER.debug("-->>Http POST请求地址：" + url);

            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);

            // 创建参数列表
            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
            if (formData != null) {
                LOGGER.debug("-->>Http POST form-data内容：" + JSON.toJSONString(formData));
                for (String key : formData.keySet()) {
                    multipartEntityBuilder.addTextBody(key, formData.get(key), ContentType.MULTIPART_FORM_DATA);
                }
            }

            httpPost.setEntity(multipartEntityBuilder.build());
            // 执行http请求
            response = httpClient.execute(httpPost);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
                LOGGER.debug("<<--Http 响应内容：" + resultString);
            } else {
                LOGGER.error("<<--Http 响应状态码：" + response.getStatusLine().getStatusCode());
                throw new RuntimeException("请求失败 状态码：" + response.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            LOGGER.error("Http 发送请求异常", e);
            throw new RuntimeException("发送请求失败 url:" + url);
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                LOGGER.error("Http 关闭流异常", e);
            }
        }
        return JSONObject.parseObject(resultString);
    }

}
